package com.clearliang.upcloudframe;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.ImageView;
import android.widget.Toast;

import com.upyun.library.common.Params;
import com.upyun.library.common.UploadEngine;
import com.upyun.library.listener.UpCompleteListener;
import com.upyun.library.listener.UpProgressListener;
import com.upyun.library.utils.UpYunUtils;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/************************************************************************************/
/*****************                   又拍云补充类                   *****************/
/*****************        新方法：根据网络url下载并上传又拍云        *****************/
/*****************                   使用前初始化                  *****************/
/*****************             一般情况下使用UpCouldUtil            *****************/
/************************************************************************************/

public class UpCouldUtilExtra {
    private static String upYun_IP = "xxx";            //又拍云服务器地址
    private static String SPACE = "xxx";               //空间名
    private static String OPERATOR = "xxx";            //操作员
    private static String PASSWORD = "xxx";            //密码
    private static String ImagePacketPlace = "xxx";    //图片在又拍云的文件夹，例如 image_packet
    private static String VideoPacketPlace = "xxx";    //视频在又拍云的文件夹，例如 video_packet

    public void initUpCloud(String serverIP,String space,String operator,String password,String imagePlaceName,String videoPlaceName){
        upYun_IP = serverIP;
        SPACE = space;
        OPERATOR = operator;
        PASSWORD = password;
        ImagePacketPlace = imagePlaceName;
        VideoPacketPlace = videoPlaceName;
    }

    public void initUpCloud(Context context){
        List list = new ArrayList();
        try {
            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder;
            builder = builderFactory.newDocumentBuilder();
            Document document = builder.parse(context.getAssets().open("xmlFile.xml"));
            Element element = document.getDocumentElement();
            NodeList nodeList = element.getElementsByTagName("item");

            for (int i = 0; i < nodeList.getLength(); i++) {
                Element item = (Element) nodeList.item(i);
                list.add(item.getElementsByTagName("value").item(0).getTextContent()+"");
            }

            upYun_IP = list.get(0).toString();
            SPACE = list.get(1).toString();
            OPERATOR = list.get(2).toString();
            PASSWORD = list.get(3).toString();
            ImagePacketPlace = list.get(4).toString();
            VideoPacketPlace = list.get(5).toString();

        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private Uri uri;
    private String real_path;
    private static Context mContext;
    private Bitmap bitmap;
    private static final long EXPIRATION = System.currentTimeMillis() / 1000 + 1000 * 5 * 10; // 过期时间，必须大于当前时间

    private static class Holder {
        private static UpCouldUtilExtra INSTANCE = new UpCouldUtilExtra();
    }

    private UpCouldUtilExtra() {
    }

    public static UpCouldUtilExtra getInstance(Context context) {
        mContext = context;
        return Holder.INSTANCE;
    }

    /**
     * 根据图片地址删除图片
     */
    public void delteImageUri(Uri uri) {
        mContext.getContentResolver().delete(uri, null, null);
    }

    /**
     * 上传图片到又拍云服务器
     */
    public void upLoad2Could(String photoPath) {
        uri = createImageUri(ImagePacketPlace);
        if (String.valueOf(uri).contains("content://")) { //如果包含有content开头，需要转化为其实际路径，不能用content开头
            real_path = getRealPathFromURI(uri, mContext);
        } else {
            real_path = String.valueOf(uri);       //如果用file开头，不用转化
        }

        File targetFile = new File(photoPath);

        Map<String, Object> map = new HashMap<>();
        map.put("bucket", SPACE);
        map.put("save-key", real_path);
        map.put("expiration", EXPIRATION);
        //验证签名
        String policy = UpYunUtils.getPolicy(map);
        String signature = UpYunUtils.getSignature(policy, PASSWORD);

        final Map<String, Object> paramsMap = new HashMap<>();
        //上传空间
        paramsMap.put(Params.BUCKET, SPACE);
        //保存路径为  时间类+文件名
        paramsMap.put(Params.SAVE_KEY, real_path);
        //请求过期时间，建议为30分钟，此处单位为秒
        paramsMap.put(Params.EXPIRATION, EXPIRATION);
        //MD5加密
        paramsMap.put(Params.CONTENT_MD5, EncryptUtils.encryptMD5File2String(targetFile));

        UpCompleteListener completeListener = new UpCompleteListener() {
            @Override
            public void onComplete(boolean isSuccess, String result) {
                if (isSuccess) {
                    LogUtil("上传成功");
                    if (listener != null) {
                        listener.successed(upYun_IP + real_path);
                        LogUtil(upYun_IP + real_path);
                    }
                } else {
                    Toast.makeText(mContext, "Upload avatar failed", Toast.LENGTH_SHORT).show();
                    LogUtil("上传失败--------------" + result);
                    if (listener != null) {
                        listener.failed(result);
                    }
                }
            }
        };
        //进度回调，可为空
        UpProgressListener progressListener = new UpProgressListener() {
            @Override
            public void onRequestProgress(final long bytesWrite, final long contentLength) {
//                uploadProgress.setProgress((int) ((100 * bytesWrite) / contentLength));
//                textView.setText((100 * bytesWrite) / contentLength + "%");
            }
        };

        //表单上传（本地签名方式）
        UploadEngine.getInstance().formUpload(
                targetFile,
                paramsMap,
                OPERATOR,
                UpYunUtils.md5(PASSWORD),
                completeListener, progressListener);

    }

    /**
     * 根据图片地址将其上传到又拍云并下载
     */
    public void upLoad2Could(String url, final ImageView image) {
        //1.创建一个okhttpclient对象
        OkHttpClient okHttpClient = new OkHttpClient();
        //2.创建Request.Builder对象，设置参数，请求方式如果是Get，就不用设置，默认就是Get
        Request request = new Request.Builder()
                .url(url)
                .build();
        //3.创建一个Call对象，参数是request对象，发送请求
        Call call = okHttpClient.newCall(request);
        //4.异步请求，请求加入调度
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //得到从网上获取资源，转换成我们想要的类型
                byte[] pic = response.body().bytes();
                //使用BitmapFactory工厂，把字节数组转化为bitmap
                bitmap = BitmapFactory.decodeByteArray(pic, 0, pic.length);
                //通过imageview，设置图片
                ((Activity) mContext).runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            LogUtil("下载成功");
                            image.setImageBitmap(bitmap);
                            bitmapSave2Could(bitmap);
                        } catch (Exception e) {
                            LogUtil(e.getMessage());
                            LogUtil("下载失败");
                        }

                    }
                });
            }

        });

    }

    private void bitmapSave2Could(Bitmap photo) {
        uri = createImageUri(ImagePacketPlace);
        if (String.valueOf(uri).contains("content://")) { //如果包含有content开头，需要转化为其实际路径，不能用content开头
            real_path = getRealPathFromURI(uri, mContext);
        } else {
            real_path = String.valueOf(uri);       //如果用file开头，不用转化
        }
        String fileName;

        fileName = Environment.getExternalStorageDirectory().getPath() + "/" + real_path;
        File targetFile = new File(fileName);
        LogUtil("fileName:" + fileName);

        if (!targetFile.getParentFile().exists()) {
            targetFile.getParentFile().mkdirs();
        } else if (!targetFile.getParentFile().isDirectory() && targetFile.getParentFile().canWrite()) {
            targetFile.delete();
            targetFile.getParentFile().mkdirs();
        }
        LogUtil(targetFile.getParentFile().exists() + "-------" + targetFile.getParentFile().getAbsolutePath());

        saveImage(photo, targetFile.getAbsolutePath());

        Map<String, Object> map = new HashMap<>();
        map.put("bucket", SPACE);
        map.put("save-key", real_path);
        map.put("expiration", EXPIRATION);
        //验证签名
        String policy = UpYunUtils.getPolicy(map);
        String signature = UpYunUtils.getSignature(policy, PASSWORD);

        final Map<String, Object> paramsMap = new HashMap<>();
        //上传空间
        paramsMap.put(Params.BUCKET, SPACE);
        //保存路径为  时间类+文件名
        paramsMap.put(Params.SAVE_KEY, real_path);
        //请求过期时间，建议为30分钟，此处单位为秒
        paramsMap.put(Params.EXPIRATION, EXPIRATION);
        //MD5加密
        paramsMap.put(Params.CONTENT_MD5, EncryptUtils.encryptMD5File2String(targetFile));

        UpCompleteListener completeListener = new UpCompleteListener() {
            @Override
            public void onComplete(boolean isSuccess, String result) {
                if (isSuccess) {
                    LogUtil("上传成功");
                    if (listener != null) {
                        listener.successed(upYun_IP + real_path);
                        LogUtil(upYun_IP + real_path);
                    }
                } else {
                    LogUtil("上传失败--------------" + result);
                    if (listener != null) {
                        listener.failed(result);
                    }
                }
            }
        };
        //进度回调，可为空
        UpProgressListener progressListener = new UpProgressListener() {
            @Override
            public void onRequestProgress(final long bytesWrite, final long contentLength) {
//                uploadProgress.setProgress((int) ((100 * bytesWrite) / contentLength));
//                textView.setText((100 * bytesWrite) / contentLength + "%");
            }
        };

        //表单上传（本地签名方式）
        UploadEngine.getInstance().formUpload(
                targetFile,
                paramsMap,
                OPERATOR,
                UpYunUtils.md5(PASSWORD),
                completeListener, progressListener);

    }

    /**
     * 上传图片成功失败的接口回调
     */
    public interface UpImageSuccess {
        void successed(String url);

        void failed(String msg);
    }

    private UpImageSuccess listener;

    public void setUpLoadListener(UpImageSuccess listener) {
        if (listener != null) {
            this.listener = listener;
        }
    }

    /**
     * 如果图片路径是以content开头的，转化为以file开头,否则找不到图片
     */
    private String getRealPathFromURI(Uri contentUri, Context context) { //传入图片uri地址
        String[] proj = {MediaStore.Images.Media.DATA};
        CursorLoader loader = new CursorLoader(context, contentUri, proj, null, null, null);
        Cursor cursor = loader.loadInBackground();
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }

    /**
     * 保存图片在指定位置
     */
    private boolean saveImage(Bitmap photo, String spath) {
        File file = new File(spath);
        try {
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
            if (photo.compress(Bitmap.CompressFormat.JPEG, 90, bos)) {
                bos.flush();
                bos.close();
                mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + file.getAbsolutePath())));
            }
        } catch (Exception e) {
            LogUtil("saveImage:" + e.getMessage());
            return false;
        }
        return true;
    }

    /**
     * 创建图片的唯一标识
     */
    private Uri createImageUri(String picName) {
        Uri imageFilePath;
        Calendar cal = Calendar.getInstance();
        String name = getUUID();//32位
        String time = picName + File.separator + cal.get(Calendar.YEAR) + File.separator + (cal.get(Calendar.MONTH) + 1) +
                File.separator + (cal.get(Calendar.DAY_OF_MONTH)) + File.separator + File.separator;
        // ContentValues是我们希望这条记录被创建时包含的数据信息
        ContentValues values = new ContentValues(3);
        values.put(MediaStore.Images.Media.DATE_TAKEN, time);
        values.put(MediaStore.Images.Media.DATA, time + name + ".jpg");
        values.put(MediaStore.Images.Media.DISPLAY_NAME, name);
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpg");
        imageFilePath = mContext.getContentResolver().insert(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        return imageFilePath;
    }

    /**
     * 根据地址下载图片给指定imageView
     */
    public void downLoadBmp(String url, final ImageView imageView) {
        //1.创建一个okhttpclient对象
        OkHttpClient okHttpClient = new OkHttpClient();
        //2.创建Request.Builder对象，设置参数，请求方式如果是Get，就不用设置，默认就是Get
        Request request = new Request.Builder()
                .url(url)
                .build();
        //3.创建一个Call对象，参数是request对象，发送请求
        Call call = okHttpClient.newCall(request);
        //4.异步请求，请求加入调度
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                LogUtil("图片下载失败");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //得到从网上获取资源，转换成我们想要的类型
                byte[] pic = response.body().bytes();
                //使用BitmapFactory工厂，把字节数组转化为bitmap
                final Bitmap bitmap = BitmapFactory.decodeByteArray(pic, 0, pic.length);

                ((Activity) mContext).runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        imageView.setImageBitmap(bitmap);
                    }
                });
            }
        });

    }

    /**
     * 如果图片路径是以content开头的，转化为以file开头,否则找不到图片
     */
    private String getRealPathFromURI(Uri contentUri) { //传入图片uri地址
        String[] proj = {MediaStore.Images.Media.DATA};
        CursorLoader loader = new CursorLoader(mContext, contentUri, proj, null, null, null);
        Cursor cursor = loader.loadInBackground();
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }

    /**
     * 获取UUID,创建唯一标识
     */
    private String getUUID() {
        return java.util.UUID.randomUUID().toString();
    }

    private void LogUtil(String msg) {
        Log.e("又拍云信息：", msg);
    }

}
